﻿using System.Collections.Generic;
using Azure.QPCR;
using Azure2Java.QPCRAdapter.Entity;
using Azure2Java.QPCRAdapter.Adapter.Entity;

namespace Azure2Java.QPCRAdapter.Adapter {

    /**
     * @author gws ssc
     * @date 19.2.27 pm
     * @update 19.12.26
     * @decription ConnectedDevice代理类
     */
    public class ConnectedDeviceAdapter {
        public ConnectedDevice ConnectedDevice;

        public ConnectedDeviceAdapter() {
            ConnectedDevice = new ConnectedDevice(new DeviceInfo());
        }

        public ConnectedDeviceAdapter(DeviceInfoAdapter DeviceInfoAdapter) {
            ConnectedDevice = new ConnectedDevice(DeviceInfoAdapter.DeviceInfo);
        }

        public ConnectedDeviceAdapter(ConnectedDevice ConnectedDevice) {
            this.ConnectedDevice = ConnectedDevice;
        }

        public bool connect() {
            return ConnectedDevice.Connect();
        }

        public void dispose() {
            ConnectedDevice.Dispose();
        }

        public bool control(string commendType) {
            switch(commendType) {
                case "connection initialization":
                    return ConnectedDevice.Control(CommandType.CONNECTION_INITIALIZATION);
                case "version check":
                    return ConnectedDevice.Control(CommandType.VERSION_CHECK);
                case "status query":
                    return ConnectedDevice.Control(CommandType.STATUS_QUERY);
                case "program run":
                    return ConnectedDevice.Control(CommandType.PROGRAM_RUN);
                case "program pause":
                    return ConnectedDevice.Control(CommandType.PROGRAM_PAUSE);
                case "program resume":
                    return ConnectedDevice.Control(CommandType.PROGRAM_RESUME);
                case "program stop":
                    return ConnectedDevice.Control(CommandType.PROGRAM_STOP);
                case "program step skip":
                    return ConnectedDevice.Control(CommandType.PROGRAM_STEP_SKIP);
                case "program download":
                    return ConnectedDevice.Control(CommandType.PROGRAM_DOWNLOAD);
                case "program get":
                    return ConnectedDevice.Control(CommandType.PROGRAM_GET);
                case "workspace summary get":
                    return ConnectedDevice.Control(CommandType.WORKSPACE_SUMMARY_GET);
                case "workspace create":
                    return ConnectedDevice.Control(CommandType.WORKSPACE_CREATE);
                case "workspace delete":
                    return ConnectedDevice.Control(CommandType.WORKSPACE_DELETE);
                case "program delete":
                    return ConnectedDevice.Control(CommandType.PROGRAM_DELETE);
                case "experiment data summary get":
                    return ConnectedDevice.Control(CommandType.EXPERIMENT_DATA_SUMMARY_GET);
                case "experiment data file info get":
                    return ConnectedDevice.Control(CommandType.EXPERIMENT_DATA_FILE_INFO_GET);
                case "experiment data file get":
                    return ConnectedDevice.Control(CommandType.EXPERIMENT_DATA_FILE_GET);
                case "experiment data file delete":
                    return ConnectedDevice.Control(CommandType.EXPERIMENT_DATA_FILE_DELETE);
                case "running experiment data file name set":
                    return ConnectedDevice.Control(CommandType.RUNNING_EXPERIMENT_DATA_FILE_NAME_SET);
                case "running experiment data upload":
                    return ConnectedDevice.Control(CommandType.RUNNING_EXPERIMENT_DATA_UPLOAD);
                case "running experiment infos get":
                    return ConnectedDevice.Control(CommandType.RUNNING_EXPERIMENT_INFOS_GET);
                case "device lock":
                    return ConnectedDevice.Control(CommandType.DEVICE_LOCK);
                case "dye summary get":
                    return ConnectedDevice.Control(CommandType.DYE_SUMMARY_GET);
                default:
                    return false;
            }
        }

        public bool createWorkspace(string workspaceName) { return ConnectedDevice.CreateWorkspace(workspaceName); }

        public bool deleteWorkspace(string workspaceName) {
            return ConnectedDevice.DeleteWorkspace(workspaceName);
        }

        public ProgramBean getProgram(string workspaceName, string programName) {
            return new ProgramBean(ConnectedDevice.GetProgram(workspaceName, programName));
        }

        public bool downloadProgram(ProgramBean programAdapter) {
            return ConnectedDevice.DownloadProgram(programAdapter.Program);
        }

        public bool deleteProgram(string workspaceName, string programName) {
            return ConnectedDevice.DeleteProgram(workspaceName, programName);
        }

        public bool setExperimentDataFileName(string workspaceName, string programName, string name) {
            return ConnectedDevice.SetRunningExperimentDataFileName(workspaceName, programName, name);
        }

        public ExperimentDataInfoAdapter getRunningExperimentInfos() {
            return new ExperimentDataInfoAdapter(ConnectedDevice.GetRunningExperimentInfos());
        }

        public bool deleteExpeimentDataFiles(ExperimentDataInfoAdapter[] experimentDataInfoAdapter) {
            List<ExperimentDataInfo> experimentDataInfoList = new List<ExperimentDataInfo>();
            for(int i = 0; i < experimentDataInfoAdapter.Length; i++) {
                experimentDataInfoList.Add(experimentDataInfoAdapter[i].ExperimentDataInfo);
            }
            return ConnectedDevice.DeleteExperimentDataFiles(experimentDataInfoList);
        }

        // 疑似无用
        public bool getWorkspaceSummary() { return ConnectedDevice.GetWorkspaceSummary(); }

        // 疑似无用
        public bool getExperimentDataSummary() { return ConnectedDevice.GetExperimentDataSummary(); }

        // 疑似无用
        public bool getExperimentDataFiles(ExperimentDataInfoAdapter[] ExperimentDataInfoAdapters, string filePath) {
            List<ExperimentDataInfo> experimentDataInfos = new List<ExperimentDataInfo>();
            for(int i = 0; i < ExperimentDataInfoAdapters.Length; i++) {
                experimentDataInfos.Add(ExperimentDataInfoAdapters[i].ExperimentDataInfo);
            }
            return ConnectedDevice.GetExperimentDataFiles(experimentDataInfos, filePath);
        }

        // 疑似无用
        public bool getDyeSummary() { return ConnectedDevice.GetDyeSummary(); }

        public bool lockDevice() { return ConnectedDevice.LockDevice(); }


        public ReceivedNormalDataBean[] getAllReceivedRunningExperimentalData() {
            //最外层的list (例allRunningExperimentalData[0]) 每一个代表每一个对应索引的step的数据，存放的是每一个step采集的数据
            //每一个List<ExperimentalData> 是对应一个step
            List<ReceivedNormalData> allReceivedRunningExperimentalData = ConnectedDevice.AllReceivedRunningExperimentalData;
            int count = allReceivedRunningExperimentalData.Count;
            ReceivedNormalData[] arr = new ReceivedNormalData[count];
            allReceivedRunningExperimentalData.CopyTo(0, arr, 0, count);

            List<ReceivedNormalDataBean> result = new List<ReceivedNormalDataBean>();
            for (int i = 0; i < arr.Length; i++) {
                result.Add(new ReceivedNormalDataBean(arr[i]));
            }
            return result.ToArray();
        }

        public ReceivedMeltingDataBean[] getAllReceivedRunningMeltingData() {
            //最外层的list (例allRunningExperimentalData[0]) 每一个代表每一个对应索引的step的数据，存放的是每一个step采集的数据
            //每一个List<ExperimentalData> 是对应一个step
            List<ReceivedMeltingData> allReceivedRunningMeltingData = ConnectedDevice.AllReceivedRunningMeltingData;
            int count = allReceivedRunningMeltingData.Count;
            ReceivedMeltingData[] arr = new ReceivedMeltingData[count];
            allReceivedRunningMeltingData.CopyTo(0, arr, 0, count);

            List<ReceivedMeltingDataBean> result = new List<ReceivedMeltingDataBean>();

            ushort position = 1, cycle = 0;
            int temperature = int.MinValue;
            List<float> d = new List<float>();

            // int count = allReceivedRunningMeltingData.Count;
            for (int i = 0; i < arr.Length; i++) {
                // if (count != allReceivedRunningMeltingData.Count) return new ReceivedMeltingDataBean[0];
                ushort _cycle = arr[i].Cycle;
                int _temperature = arr[i].Temperature;
                if(cycle != _cycle || temperature != _temperature) {
                    while(position++ != 7) {
                        for(int j = 0; j < 16; j++) d.Add(0);
                    }

                    if(cycle > 0)
                        result.Add(new ReceivedMeltingDataBean(cycle, temperature, d.ToArray()));

                    position = 1;
                    cycle = _cycle;
                    temperature = _temperature;
                    d = new List<float>();
                }
                if(arr[i].Position != position++) {
                    do {
                        for(int j = 0; j < 16; j++) d.Add(0);
                    } while(arr[i].Position != position++);
                }
                foreach(float f in arr[i].Data) d.Add(f);
            }

            if(cycle > 0)
                result.Add(new ReceivedMeltingDataBean(cycle, temperature, d.ToArray()));

            return result.ToArray();
        }

        public DeviceInfoAdapter getDeviceInfo() {
            return new DeviceInfoAdapter(ConnectedDevice.DeviceInfo);
        }

        public DyeDictionary[] getDyeList() {
            List<DyeDictionary> dyeList = new List<DyeDictionary>();
            foreach(var list in ConnectedDevice.DyeSummary) {
                dyeList.Add(new DyeDictionary(list.Key, list.Value.ToArray()));
            }
            return dyeList.ToArray();
        }

        public WorkspaceBean[] getDataManagerWorkspace() {
            List<WorkspaceBean> result = new List<WorkspaceBean>();
            foreach(var workspace in ConnectedDevice.ExperimentDataSummary) {
                List<ProtocolBean> p = new List<ProtocolBean>();
                foreach(var protocol in workspace.Value) {
                    List<ExperimentDataInfoAdapter> e = new List<ExperimentDataInfoAdapter>();
                    foreach(var item in protocol.Value) {
                        e.Add(new ExperimentDataInfoAdapter(item));
                    }
                    p.Add(new ProtocolBean(protocol.Key, e.ToArray()));
                }
                result.Add(new WorkspaceBean(workspace.Key, p.ToArray()));
            }
            return result.ToArray();
        }

        public void setDataManagerWorkspace(WorkspaceBean[] workspace) {
            Dictionary<string, Dictionary<string, List<ExperimentDataInfo>>> experimentDataSummary = new Dictionary<string, Dictionary<string, List<ExperimentDataInfo>>>();
            foreach(var w in workspace) {
                Dictionary<string, List<ExperimentDataInfo>> protocol = new Dictionary<string, List<ExperimentDataInfo>>();
                foreach(var p in w.getProtocols()) {
                    List<ExperimentDataInfo> experiment = new List<ExperimentDataInfo>();
                    foreach(var e in p.getExperimentDataInfo()) {
                        experiment.Add(e.ExperimentDataInfo);
                    }
                    protocol.Add(p.getName(), experiment);
                }
                experimentDataSummary.Add(w.getName(), protocol);
            }
            ConnectedDevice.ExperimentDataSummary = experimentDataSummary;
        }

        public WorkspaceBean[] getWorkspaceProtocol() {
            List<WorkspaceBean> result = new List<WorkspaceBean>();
            foreach(var workspace in ConnectedDevice.WorkspaceSummary) {
                List<ProtocolBean> p = new List<ProtocolBean>();
                foreach(var protocol in workspace.Value) {
                    p.Add(new ProtocolBean(protocol, null));
                }
                result.Add(new WorkspaceBean(workspace.Key, p.ToArray()));
            }
            return result.ToArray();
        }

        public void setWorkspaceProtocol(WorkspaceBean[] workspace) {
            Dictionary<string, List<string>> workspaceSummary = new Dictionary<string, List<string>>();
            foreach(var w in workspace) {
                List<string> protocol = new List<string>();
                foreach(var p in w.getProtocols()) {
                    protocol.Add(p.getName());
                }
                workspaceSummary.Add(w.getName(), protocol);
            }
            ConnectedDevice.WorkspaceSummary = workspaceSummary;
        }

        public bool isAlive() {
            return ConnectedDevice.IsAlive;
        }

        public void setAlive(bool status) {
            ConnectedDevice.IsAlive = status;
        }

        public StatusBean getStatus() {
            return new StatusBean(ConnectedDevice.Status);
        }
    }
}
